package com.googlecode.openrtp.grizzly.rtp.filter;

import com.googlecode.openrtp.grizzly.FilterAttributes;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import javax.inject.Inject;
import org.glassfish.grizzly.filterchain.BaseFilter;
import org.glassfish.grizzly.filterchain.FilterChainContext;
import org.glassfish.grizzly.filterchain.NextAction;
import com.googlecode.openrtp.grizzly.RtpSessionFactory;
import com.googlecode.openrtp.spi.RtpPacket;
import com.googlecode.openrtp.spi.RtpSession;
import com.googlecode.openrtp.spi.RtpSessionManager;
import com.googlecode.openrtp.spi.annotation.Priority;
import java.util.logging.Logger;
import org.glassfish.grizzly.memory.CompositeBuffer;

/**
 *
 * @author jocke
 */
@Priority(intValue = Integer.MAX_VALUE)
public class RtpSessionFilter extends BaseFilter {

    private final RtpSessionManager sessionManager;

    private final RtpSessionFactory sessionFactory;
    
    private static final Logger LOG = Logger.getLogger(RtpSessionFilter.class.getName());

    @Inject
    public RtpSessionFilter(RtpSessionManager sessionManager, RtpSessionFactory sessionFactory) {
        this.sessionManager = sessionManager;
        this.sessionFactory = sessionFactory;
    }

    @Override
    public NextAction handleRead(FilterChainContext ctx) throws IOException {

        RtpPacket packet = ctx.getMessage();

        RtpSession lookup = sessionManager.lookup(packet.getSsrc());

        if (lookup == null) {
            RtpSession session = sessionFactory.create(packet.getSsrc());
            sessionManager.register(session, packet.getSsrc());
            InetSocketAddress peerAddress = (InetSocketAddress) ctx.getAddress();
            session.connectRtcp(peerAddress.getHostName(), peerAddress.getPort() + 1);
        }

        return super.handleRead(ctx);
    }

    @Override
    public NextAction handleWrite(FilterChainContext ctx) throws IOException {        
        RtpSession session = ctx.getMessage();
        ctx.getAttributes().setAttribute(FilterAttributes.SESSION, session);
        CompositeBuffer buffer = CompositeBuffer.newBuffer(ctx.getMemoryManager());
        buffer.put(session .retrieveDataFromOutBuffer());
        return super.handleWrite(ctx);
    }

}
